/** @file         lzm_bus.c
 *  @brief        我的总线文件
 *  @details      基于驱动模块的方式实现 总线注册/注销等等操作。
 *  @author       lzm
 *  @date         2021-03-21 10:19:03
 *  @version      v1.0
 *  @copyright    Copyright By lizhuming, All Rights Reserved
 *
 **********************************************************
 *  @LOG 修改日志:
 **********************************************************
*/


#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>


/* [bus][1] */
/* 实现总线结构体内容 */
/** @brief  lzm_bus_match
  * @param  dev：设备结构体
  * @param  drv：驱动结构体
  * @retval 1：成功。 0：失败。
  * @author lzm
  */
int lzm_bus_match(struct device *dev, struct device_driver *drv)
{
    printk("%s-%s\n", __FILE__, __func__); // 打印文件及函数
    
    if(!strncmp(dev_name(dev), drv->name, strlen(drv->name)))
    {
        printk("dev & drv match succss!\n");
        return 1;
    }
    return 0;
}

/* [bus][2] */
/* 填充总线结构体 */
static struct bus_type lzm_bus =
{
    .name = "lzm_xbus", // 总线名称
    .match = lzm_bus_match, // 匹配函数
};
/* 广播 */
EXPORT_SYMBOL(lzm_bus);

/* [bus][3] */
/* 实现属性文件内容 */
/* 实现 show 回调函数，让用户能通过 cat 命令获取总线名称 */
/** @brief  lzm_bus_show
  * @param  
  * @retval 
  * @author lzm
  */
static char *bus_name = "lzm_bus";
ssize_t lzm_bus_show(struct bus_type *bus, char *buf)
{
    return sprintf(buf, "%s\n", bus_name); // 拷贝到 buf 中
}
// 设置该文件 名称、属性等等
BUS_ATTR(xxx_bus, S_IRUSR, lzm_bus_show, NULL); // xxx_bus 为 bus 属性文件名称。在 /sys/bus/<bus-name> 下




/* [module][1] */
/** @brief   lzm_bus_init
  * @details bus module 入口函数
  * @param  
  * @retval 
  * @author lzm
  */
static int __init lzm_bus_init(void)
{
    printk("lzm_bus init!\n");
    
    /* [bus][4] 注册总线 */
    (void)bus_register(&lzm_bus);

    /* [bus][5] 创建属性文件*/
    (void)bus_create_file(&lzm_bus, &bus_attr_xxx_bus); // 创建后会在 /sys/bus/<bus-name> 下。bus_attr_xxx_bus 参考 BUS_ARRT 源码。bus_attr_##name。

    return 1;
}
module_init(lzm_bus_init);

/* [module][2] */
/** @brief   lzm_bus_exit
  * @details bus module 出口函数
  * @param  
  * @retval 
  * @author lzm
  */
static void __exit lzm_bus_exit(void)
{
    printk("lzm_bus exit!\n");

    /* [bus][6] 删除属性文件 */
    bus_remove_file(&lzm_bus, &bus_attr_xxx_bus);

    /* [bus][7] 注销总线 */
    bus_unregister(&lzm_bus);
}
module_exit(lzm_bus_exit);

/* [module][3] */
MODULE_AUTHOR("lizhuming");
MODULE_LICENSE("GPL");

